package javbot.util;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * Thumbnail.java (requires Java 1.2+)
 * Load an image, scale it down and save it as a JPEG file.
 * @author Marco Schmidt
 */
public class Jpeg {
			
	public static void processImage(File inFile, File outFile, int quality) throws Exception {
		Jpeg.processImage2(inFile, outFile, quality, false, new Dimension(0,0), false, 0);	}
		
	public static void processImage(File inFile, File outFile, int quality, Dimension outSize) throws Exception {
		Jpeg.processImage2(inFile, outFile, quality, true, outSize, false, 0 );
	}
	
	/**
	 * 
	 * @param inFile
	 * @param outFile
	 * @param quality Quality: 0-100%
	 * @param scaling Scaling: 0-1000%
	 * @throws Exception
	 */
	public static void processImageWithQualityAndScaling(File inFile, File outFile, int quality, int scaling) throws Exception {
		Jpeg.processImage2(inFile, outFile, quality, false, null, true, ((double) scaling) / 100.0 );
	}	
	
	
	private static void  processImage2(File inFile, File outFile, int quality, boolean resize, Dimension thumbSize, boolean scale, double scaling) throws Exception {
				
		Image imageIn = loadImage(inFile);

		// determine thumbnail size from WIDTH and HEIGHT
		int imageWidth = imageIn.getWidth(null);
		int imageHeight = imageIn.getHeight(null);
		
		System.out.println("Source width: "  + imageWidth + "px");
		System.out.println("Source height: "  + imageHeight + "px");
			
		
		if (thumbSize == null)
			thumbSize = new Dimension();
		
		if (resize) {
			double thumbRatio = (double) thumbSize.width / (double) thumbSize.height;
			double imageRatio = (double) imageWidth / (double) imageHeight;
			if (thumbRatio < imageRatio) {
				thumbSize.height = (int) (thumbSize.width / imageRatio);
			} else {
				thumbSize.width = (int) (thumbSize.height * imageRatio);
			}
		}
		else if (scale) {
			thumbSize.width = (int) (imageWidth * scaling);
			thumbSize.height = (int) (imageHeight * scaling);
		} else {
			thumbSize.width = imageWidth;
			thumbSize.height = imageHeight;
		}
		
		System.out.println("Target width: "  + thumbSize.width + "px");
		System.out.println("Target height: "  + thumbSize.height + "px");
		
		processImage3(imageIn, outFile, quality, thumbSize.width, thumbSize.height);
		System.out.println("Target: "  + outFile.length()+ " bytes");
		System.out.println("Compr.: "  + ((double) Math.round(((double) outFile.length() / (double) inFile.length()) * 10000)/100) + "%");
	}


	private static void processImage3(Image imageIn, File outFile, int quality, int thumbWidth, int thumbHeight) throws FileNotFoundException, IOException {
		// draw original image to thumbnail image object and
		// scale it to the new size on-the-fly
		BufferedImage imageOut = new BufferedImage(thumbWidth, thumbHeight,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D graphics2D = imageOut.createGraphics();
		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		graphics2D.drawImage(imageIn, 0, 0, thumbWidth, thumbHeight, null);
		// save thumbnail image to OUTFILE
		BufferedOutputStream out = new BufferedOutputStream(
				new FileOutputStream(outFile));
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(imageOut);
		quality = Math.max(0, Math.min(quality, 100));
		param.setQuality((float) quality / 100.0f, false);
		System.out.println("Quality: "  + quality + "/100");
		encoder.setJPEGEncodeParam(param);
		encoder.encode(imageOut);
		out.close();
	}

	private static Image loadImage(File inFile) throws InterruptedException {
		System.out.println("Source: "  + inFile.length() + " bytes");
		// load image from INFILE
		Image imageIn = Toolkit.getDefaultToolkit().getImage(inFile.getName());
		MediaTracker mediaTracker = new MediaTracker(new Container());
		mediaTracker.addImage(imageIn, 0);
		mediaTracker.waitForID(0);
		return imageIn;
	}
}